#include "../common/config.h"

#ifdef USE_LOG4CXX
#include <log4cxx/logstring.h>
#include <log4cxx/defaultloggerfactory.h>
#include <log4cxx/spi/loggerrepository.h>
#include <log4cxx/logmanager.h>
#include <log4cxx/patternlayout.h>
#include <log4cxx/rollingfileappender.h>
#include "../httpproxy/httpconfig.h"
#include "../httpproxy/httpproxy.h"
#endif

#include "logmanager.h"

#ifdef WIN32
#include <windows.h>
#else
#include <syslog.h>
#endif

using namespace std;

#ifndef NO_INITLOG
// use to log errors before reading logging settings
void LogManager::initlog(const string & logstr)
{
#ifdef WIN32
	HANDLE hEventSource;

	hEventSource = RegisterEventSource(NULL, TEXT("XRelayer"));
	if (hEventSource != NULL)
	{
		LPTSTR  lpszStrings[1];
		TCHAR   szMsg[256];
		_snprintf(szMsg, 255, "%s", logstr.c_str());
		szMsg[255] = (TCHAR)0;
		lpszStrings[0] = szMsg;
		ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR *)lpszStrings, NULL);
		(VOID) DeregisterEventSource(hEventSource);
	}
#else
	openlog("XRelayer", LOG_CONS | LOG_PID, LOG_DAEMON | LOG_LOCAL7);
	syslog(LOG_ERR, "%s", logstr.c_str());
#endif
}
#endif

#ifdef USE_LOG4CXX
void LogManager::configure()
{
	HTTPConfig& config = HTTPProxy::getInstance().getConfig();

	if(config.isLogEnabled() == false)
		return;
	
	log4cxx::spi::LoggerFactoryPtr loggerFactory = new log4cxx::DefaultLoggerFactory();
	log4cxx::spi::LoggerRepositoryPtr& logrepo = log4cxx::LogManager::getLoggerRepository();

	LogConfig httpproxy_config = config.getProxyLogConfig();
	if(httpproxy_config.m_name == "httpproxy")
	{
		const log4cxx::LogString httpproxy_name(LOG4CXX_STR("httpproxy"));
		const log4cxx::LogString httpproxy_pattern(LOG4CXX_STR("%d{yyyy/MM/dd HH:mm:ss} [%-5p] %m%n"));
		const log4cxx::LogString httpproxy_file(LOG4CXX_STR(httpproxy_config.m_filename));
		log4cxx::LoggerPtr httpproxy_logger = logrepo->getLogger(httpproxy_name, loggerFactory);
		log4cxx::LayoutPtr httpproxy_layout = new log4cxx::PatternLayout(httpproxy_pattern);
		log4cxx::RollingFileAppender* appender = new log4cxx::RollingFileAppender(httpproxy_layout, httpproxy_file, true);
		appender->setMaxBackupIndex(httpproxy_config.m_backupindex);
		log4cxx::AppenderPtr httpproxy_appender = appender;
		httpproxy_logger->setLevel(log4cxx::Level::toLevel(httpproxy_config.m_level));
		httpproxy_logger->addAppender(httpproxy_appender);
	}

	LogConfig access_config = config.getAccessLogConfig();
	if(access_config.m_name == "access")
	{
		const log4cxx::LogString access_name(LOG4CXX_STR("access"));
		const log4cxx::LogString access_pattern(LOG4CXX_STR("%d{yyyy/MM/dd HH:mm:ss} [%-5p] %m%n"));
		const log4cxx::LogString access_file(LOG4CXX_STR(access_config.m_filename));
		log4cxx::LoggerPtr access_logger = logrepo->getLogger(access_name, loggerFactory);
		log4cxx::LayoutPtr access_layout = new log4cxx::PatternLayout(access_pattern);
		log4cxx::RollingFileAppender* appender = new log4cxx::RollingFileAppender(access_layout, access_file, true);
		appender->setMaxBackupIndex(access_config.m_backupindex);
		log4cxx::AppenderPtr access_appender = appender;
		access_logger->setLevel(log4cxx::Level::toLevel(access_config.m_level));
		access_logger->addAppender(access_appender);
	}

	LogConfig debugger_config = config.getDebuggerConfig();
	if(debugger_config.m_name == "debugger")
	{
		const log4cxx::LogString debugger_name(LOG4CXX_STR("debugger"));
		const log4cxx::LogString debugger_pattern(LOG4CXX_STR("%d{yyyy/MM/dd HH:mm:ss} [%-5p] %m%n"));
		const log4cxx::LogString debugger_file(LOG4CXX_STR(debugger_config.m_filename));
		log4cxx::LoggerPtr debugger_logger = logrepo->getLogger(debugger_name, loggerFactory);
		log4cxx::LayoutPtr debugger_layout = new log4cxx::PatternLayout(debugger_pattern);
		log4cxx::RollingFileAppender* appender = new log4cxx::RollingFileAppender(debugger_layout, debugger_file, true);
		appender->setMaxBackupIndex(debugger_config.m_backupindex);
		log4cxx::AppenderPtr debugger_appender = appender;
		debugger_logger->setLevel(log4cxx::Level::toLevel(debugger_config.m_level));
		debugger_logger->addAppender(debugger_appender);
	}
}

#endif

